package cmd

import (
	"context"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcmd"
	"github.com/gogf/gf/v2/os/gproc"
	"github.com/gogf/gflock"
	"server/internal/crons"
	"server/internal/library/crontab"
	"server/internal/service"
)

// 由于进程间资源是独立存在的，若定时任务单独运行，则无法便捷操作进程中已启动的定时任务（进程间通信比较麻烦）
// 因此考虑定时任务和http服务一起运行，可以通过api直接操作相关定时任务（关闭、重启定时任务）

var Cron = &gcmd.Command{
	Name:  "cron",
	Usage: "cron",
	Brief: "定时任务",
	Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
		// 上文件锁
		lockFile := "./crontab.lock"
		if res, err := g.Cfg().Get(ctx, "system.crontabFileLockPath"); err == nil && len(res.String()) > 0 {
			lockFile = res.String()
		}
		lock := gflock.New(lockFile)
		if !lock.TryLock() {
			crontab.Logger().Debug(ctx, "repeat start crontab task")
			return
		}

		crontab.Logger().Debugf(ctx, "crontab running, process id[%v]", gproc.Pid())

		//注册定时任务
		crons.Register()

		//启动定时任务
		err = service.SystemCrontab().StartAllCrontab(ctx)
		if err != nil {
			crontab.Logger().Debugf(ctx, "crontab start fail: %s", err.Error())
			return
		}

		serverWg.Add(1)

		// 监听进程退出的信号
		signalListen(ctx, signalHandlerForOverall)

		//由于定时任务都是异步开启，因此要在此阻塞监听进程关闭事件
		<-serverCloseSignal
		crontab.Logger().Debug(ctx, "crontab receive close signal")

		// 删除所有定时任务
		crontab.DeleteAllTasks()

		//删除定时任务运行锁
		_ = lock.Unlock()
		serverWg.Done()

		crontab.Logger().Debug(ctx, "crontab closed")

		return
	},
}
